public class ActionOrder {
    /**
     * 活动安排问题（贪心算法）
     * @author ShakeJ
     * @date 2024/1/2
     */

    /**
     * 设有n个活动的集合E={1,2,…,n}，其中每个活动都要求使用同一资源，如演讲会场等，
     * 而在同一时间内只有一个活动能使用这一资源。每个活动i都有一个要求使用该资源的起始时间si和一个结束时间fi,且si <fi。
     * 如果选择了活动i，则它在半开时间区间[si, fi)内占用资源。若区间[si, fi)与区间[sj, fj)不相交,则称活动i与活动j是相容的。
     * 也就是说，当si≥fj或sj≥fi时，活动i与活动j相容。
     * 活动安排问题就是要在所给的活动集合中选出最大的相容活动子集合。
     */

    public int greedySelector(int[] s,int []f,boolean[]a){
        int n=s.length-1;
        a[1]=true; //第一个活动被选中的话
        int j=0;
        int count=0; //统计被选中的活动的数量
        for(int i=1;i<=n;i++){
            if(s[i]>=f[j]){
                a[i]=true;
                j=i;
                count++;
            }else {
                a[i]=false;
            }
        }
        return count;
    }

    public static void main(String[] args) {
        int s[]={-1,1,3,0,5,3,5,6,8,8,2,12};//默认下标从1开始（已非减序排好序），初始的-1无用
        int f[]={-1,4,5,6,7,8,9,10,11,12,13,14}; //此时结束数组已经按照从小到大的顺序进行排列了
        boolean[] a=new boolean[s.length];
        ActionOrder ac=new ActionOrder();
        int counts=ac.greedySelector(s,f,a);
        System.out.println("活动集合中的最大相容活动数量为："+counts);
        for(int i=1;i<= s.length-1;i++){
            if(a[i]){
                System.out.println("第"+i+"活动被选中，开始时间为： "+s[i]+"结束时间为： "+f[i]);
            }
        }
    }
}
